};
#define ACPI_2_0_TCPA_LAML_SIZE (64*1024)
+/*
+ * Fixed ACPI Description Table Structure (FADT) in ACPI 1.0.
+ */
+struct acpi_10_fadt {
+ struct acpi_header header;
+ uint32_t firmware_ctrl;
+ uint32_t dsdt;
+ uint8_t reserved0;
+ uint8_t preferred_pm_profile;
+ uint16_t sci_int;
+ uint32_t smi_cmd;
+ uint8_t acpi_enable;
+ uint8_t acpi_disable;
+ uint8_t s4bios_req;
+ uint8_t pstate_cnt;
+ uint32_t pm1a_evt_blk;
+ uint32_t pm1b_evt_blk;
+ uint32_t pm1a_cnt_blk;
+ uint32_t pm1b_cnt_blk;
+ uint32_t pm2_cnt_blk;
+ uint32_t pm_tmr_blk;
+ uint32_t gpe0_blk;
+ uint32_t gpe1_blk;
+ uint8_t pm1_evt_len;
+ uint8_t pm1_cnt_len;
+ uint8_t pm2_cnt_len;
+ uint8_t pm_tmr_len;
+ uint8_t gpe0_blk_len;
+ uint8_t gpe1_blk_len;
+ uint8_t gpe1_base;
+ uint8_t cst_cnt;
+ uint16_t p_lvl2_lat;
+ uint16_t p_lvl3_lat;
+ uint16_t flush_size;
+ uint16_t flush_stride;
+ uint8_t duty_offset;
+ uint8_t duty_width;
+ uint8_t day_alrm;
+ uint8_t mon_alrm;
+ uint8_t century;
+ uint16_t iapc_boot_arch;
+ uint8_t reserved1;
+ uint32_t flags;
+};
+
/*
* Fixed ACPI Description Table Structure (FADT).
*/
#define ACPI_2_0_XSDT_REVISION 0x01
#define ACPI_2_0_TCPA_REVISION 0x02
#define ACPI_2_0_HPET_REVISION 0x01
+#define ACPI_1_0_FADT_REVISION 0x01
#pragma pack ()
struct acpi_20_rsdt *rsdt;
struct acpi_20_xsdt *xsdt;
struct acpi_20_fadt *fadt;
+ struct acpi_10_fadt *fadt_10;
struct acpi_20_facs *facs;
unsigned char *dsdt;
unsigned long secondary_tables[16];
memcpy(dsdt, &AmlCode, DsdtLen);
offset += align16(DsdtLen);
+ /*
+ * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2
+ * or above properly, notably Windows 2000, which tries to copy FADT
+ * into a 116 bytes buffer thus causing an overflow. The solution is to
+ * link the higher revision FADT with the XSDT only and introduce a
+ * compatible revision 1 FADT that is linked with the RSDT. Refer to:
+ * http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt
+ */
+ fadt_10 = (struct acpi_10_fadt *)&buf[offset];
+ memcpy(fadt_10, &Fadt, sizeof(struct acpi_10_fadt));
+ offset += align16(sizeof(struct acpi_10_fadt));
+ fadt_10->header.length = sizeof(struct acpi_10_fadt);
+ fadt_10->header.revision = ACPI_1_0_FADT_REVISION;
+ fadt_10->dsdt = (unsigned long)dsdt;
+ fadt_10->firmware_ctrl = (unsigned long)facs;
+ set_checksum(fadt_10,
+ offsetof(struct acpi_header, checksum),
+ sizeof(struct acpi_10_fadt));
+
fadt = (struct acpi_20_fadt *)&buf[offset];
memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
offset += align16(sizeof(struct acpi_20_fadt));
rsdt = (struct acpi_20_rsdt *)&buf[offset];
memcpy(rsdt, &Rsdt, sizeof(struct acpi_header));
- rsdt->entry[0] = (unsigned long)fadt;
+ rsdt->entry[0] = (unsigned long)fadt_10;
for ( i = 0; secondary_tables[i]; i++ )
rsdt->entry[i+1] = secondary_tables[i];
rsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint32_t);